home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1995
/
MacHack 1995.toast
/
Presentations
/
Presentations ’91
/
MPW Stand-Alone Libraries
/
Macros.a
< prev
next >
Wrap
Text File
|
1991-06-13
|
10KB
|
521 lines
;These macros are for the 68000.
;They have not been optimized for the 68010, 68020 or 68030.
;Some of these macros work only in supervisor mode on a
;68000 due to use of screwed up CCR instructions.
;Do an EQU if the symbol is not already defined.
MACRO
&symbol Default &value
IF &Type(&symbol)='UNDEFINED' THEN
&symbol: EQU &value
ENDIF
ENDM
;Ensure that a condition is true.
MACRO
Ensure &condition
IF &Eval(&condition)=0 THEN
AERROR 'Ensure failed.'
ENDIF
ENDM
;End a RECORD and declare a size field.
MACRO
ENDRSize
ORG
size: EQU *
ENDR
ENDM
;Reserve space on a stack.
MACRO
RSRV.&size &number
LCLA &bytes
IF &number = '' THEN
&bytes: SETA 1
ELSE
&bytes: SETA &Eval(&number)
ENDIF
IF &size='L' THEN
&bytes: SETA 4*&bytes
ELSEIF &size='W' THEN
&bytes: SETA 2*&bytes
ELSEIF &size='B' THEN
ELSE
AERROR &CONCAT('RSRV: ',&size,' is a bad size.')
ENDIF
&bytes: SETA ((&bytes+1) AND (~1))
IF &bytes<32767 THEN
SUB.W #&bytes,SP
ELSE
SUB.L #&bytes,SP
ENDIF
ENDM
;Free space from a stack.
MACRO
FREE.&size &number
LCLA &bytes
IF &number = '' THEN
&bytes: SETA 1
ELSE
&bytes: SETA &Eval(&number)
ENDIF
IF &size='L' THEN
&bytes: SETA 4*&bytes
ELSEIF &size='W' THEN
&bytes: SETA 2*&bytes
ELSEIF &size='B' THEN
ELSE
AERROR &CONCAT('FREE: ',&size,' is a bad size.')
ENDIF
&bytes: SETA ((&bytes+1) AND (~1))
IF &bytes<32767 THEN
ADD.W #&bytes,SP
ELSE
ADD.L #&bytes,SP
ENDIF
ENDM
;Move condition codes.
MACRO
MOVECCR &destination
MOVE.W SR,&destination
ENDM
;Save some registers on the stack, possibly changing the condition codes.
MACRO
Save ®isters,&preserve==0
GBLC &savedRegisters
GBLA &port
IF &savedRegisters<>'' THEN
AERROR 'Two Saves without an intervening Restore.'
ENDIF
&port: SETA 0
IF ®isters='' THEN
&savedRegisters: SETC 'None'
ELSEIF ®isters='thePort' THEN
&savedRegisters: SETC 'None'
&port: SETA 1
ELSE
IF &SubStr(®isters,&Len(®isters)-7,8)='/thePort' THEN
&savedRegisters: SETC &SubStr(®isters,1,&Len(®isters)-8)
&port: SETA 1
ELSE
&savedRegisters: SETC ®isters
ENDIF
IF &SubStr(&Type(&savedRegisters),1,5)='REG A' THEN
MOVE.L &savedRegisters,-(SP)
ELSEIF &SubStr(&Type(&savedRegisters),1,4)='REG ' THEN
IF &preserve THEN
MOVEM.L &savedRegisters,-(SP)
ELSE
MOVE.L &savedRegisters,-(SP)
ENDIF
ELSE
MOVEM.L &savedRegisters,-(SP)
ENDIF
ENDIF
IF &port THEN
RSRV.L
MOVEM.L D0-D2/A0-A1,-(SP)
IF &preserve THEN
MOVECCR -(SP)
PEA 2+5*4(SP)
ELSE
PEA 5*4(SP)
ENDIF
_GetPort
IF &preserve THEN
MOVE.W (SP)+,CCR
ENDIF
MOVEM.L (SP)+,D0-D2/A0-A1
ENDIF
IF debug THEN
PEA ('Save')
ENDIF
ENDM
;Restore some registers saved by a Save macro.
MACRO
Restore &preserve==0
GBLC &savedRegisters
GBLA &port
IF &savedRegisters='' THEN
AERROR 'Restore without Save.'
ELSE
IF debug THEN
IF &preserve THEN
MOVECCR -(SP)
CMP.L #'Save',2(SP)
ELSE
CMP.L #'Save',(SP)+
ENDIF
BEQ.S @goodSave
_Debugger
@goodSave:
IF &preserve THEN
MOVE.W (SP)+,CCR
ADDQ.W #4,SP
ENDIF
ENDIF
IF &port THEN
IF &preserve THEN
MOVECCR -(SP)
MOVE.L 2(SP),-(SP)
_SetPort
MOVE.W (SP)+,CCR
FREE.L
ELSE
MOVEM.L D0-D2/A0-A1,-(SP)
IF &preserve THEN
MOVECCR -(SP)
MOVE.L 2+5*4(SP),-(SP)
ELSE
MOVE.L 5*4(SP),-(SP)
ENDIF
_SetPort
IF &preserve THEN
MOVE.W (SP)+,CCR
ENDIF
MOVEM.L (SP)+,D0-D2/A0-A1
FREE.L
ENDIF
ENDIF
IF &savedRegisters<>'None' THEN
IF &SubStr(&Type(&savedRegisters),1,5)='REG A' THEN
MOVE.L (SP)+,&savedRegisters
ELSEIF &SubStr(&Type(&savedRegisters),1,4)='REG ' THEN
IF &preserve THEN
MOVEM.L (SP)+,&savedRegisters
ELSE
MOVE.L (SP)+,&savedRegisters
ENDIF
ELSE
MOVEM.L (SP)+,&savedRegisters
ENDIF
ENDIF
&savedRegisters: SETC ''
ENDIF
ENDM
;Pad a piece of memory to BlockSize items (item is either bytes, words, or longs).
MACRO
Pad.&size &blockSize,&startLabel,&itemValue=0
LCLC &itemType
LCLA &padItems
&PadItems: SETA &Eval(&BlockSize)-(*-&Eval(&StartLabel))
IF &size='' THEN
&itemType: SETC 'B'
ELSEIF &size='B' THEN
&itemType: SETC 'B'
ELSEIF &size='W' THEN
&ItemType: SETC 'W'
&padItems: SETA &padItems DIV 2
ELSEIF &size='L' THEN
&itemType: SETC 'L'
&padItems: SETA &padItems DIV 4
ELSE
AERROR &Concat('Pad cannot handle unknown item length: ',&size)
ENDIF
IF &padItems<0 THEN
AERROR 'Pad cannot pad a block bigger than the block size.'
ELSEIF &padItems>0 THEN
DCB.&itemType &padItems,&itemValue
ENDIF
ENDM
;Create a jump table starting with the label and having a given prefix.
MACRO
&name Table &prefix,&base
LCLC &tableName
GBLC &tablePrefix,&tableBase
IF &name = '' THEN
&tableName: SETC 'Table'
ELSE
&tableName: SETC &name
ENDIF
&tablePrefix: SETC &prefix
IF &base = '' THEN
&tableBase: SETC &tableName
ELSEIF &UpCase(&base) = 'ABSOLUTE' THEN
&tableBase: SETC ''
ELSE
&tableBase: SETC &base
ENDIF
&tableName:
ENDM
;Create a jump table entry.
MACRO
DT.&size &entry
GBLC &tablePrefix,&tableBase
IF &tableBase = '' THEN
DC.&size &Concat(&tablePrefix,&entry)
ELSE
DC.&size &Concat(&tablePrefix,&entry,'-',&tableBase)
ENDIF
ENDM
;Create a stack frame.
MACRO
&frame Frame ¶meters=0
GBLC &frameName,&frameState,&WITHStatus,&ENDWITHMod
IF &WITHStatus = 'NeedENDWITH' THEN
IF &SysMod = &ENDWITHMod THEN
ENDWITH
ENDIF
ENDIF
&WITHStatus: SETC ''
IF &frameState = '' THEN
IF &frame = '' THEN
&frameName: SETC 'Frame'
ELSE
&frameName: SETC &frame
ENDIF
&frameName: RECORD {Link},DECR
FrameStart: EQU *
&frameState: SETC 'Frame'
ENDIF
IF &frameState = 'Frame' THEN
IF ¶meters = 0 THEN
ORG
ParameterSize: EQU FrameStart-*
Return: DS.L 1
Link: DS.L 1
&frameState: SETC 'Link'
ENDIF
ELSE
AERROR 'Two Frames without intervening EndFrame.'
ENDIF
ENDM
;Declare some parameters.
MACRO
&Frme ParameterFrame
&Frme Frame parameters=1
ENDM
;Declare some locals.
MACRO
LocalFrame
Frame parameters=0
ENDM
;End a stack frame.
MACRO
EndFrame
GBLC &frameName,&frameState,&WITHStatus
IF &frameState = 'Frame' THEN
Frame
ENDIF
IF &frameState = 'Link' THEN
ORG
LocalSize: EQU *
ENDR
&frameState: SETC ''
&WITHStatus: SETC 'NeedWITH'
ELSE
AERROR 'EndFrame without proper balancing Frame.'
ENDIF
ENDM
;Hide the cursor.
MACRO
HideCursor
_HideCursor
ENDM
;Show the cursor.
MACRO
ShowCursor
MOVE.B #1,CrsrBusy ;lock out the cursor routines
CMP.W #-1,CrsrState ;will the cursor be made visible?
BLT.S @doShow ;no, don't unobscure
CLR.B CrsrObscure ;turn off the obscure flag
@doShow:
_ShowCursor ;start the cursor back up
ENDM
;LINK.
MACRO
doLINK &size
GBLC &LINKstate,&frameName,&WITHStatus,&ENDWITHMod
IF &LINKstate <> '' THEN
AERROR 'missing UNLK'
ENDIF
IF &WITHStatus = 'NeedWITH' THEN
WITH &frameName
&WITHStatus: SETC 'NeedENDWITH'
&ENDWITHMod: SETC &SysMod
ENDIF
IF &size='' THEN
LINK A6,#LocalSize
ELSE
LINK A6,#&size
ENDIF
IF debug THEN
PEA ('LINK')
ENDIF
&LINKState: SETC 'doLINK'
ENDM
;Fake LINK.
MACRO
noLINK
GBLC &LINKstate
IF &LINKstate <> '' THEN
AERROR 'missing UNLK'
ENDIF
IF debug THEN
LINK A6,#0
UNLK A6
ENDIF
&LINKState: SETC 'noLINK'
ENDM
;UNLK.
MACRO
doUNLK &preserve==0
GBLC &LINKstate
IF &LINKstate = '' THEN
AERROR 'missing LINK'
ENDIF
IF &LINKstate = 'doLINK' THEN
IF debug THEN
IF &preserve THEN
MOVECCR -(SP)
CMP.L #'LINK',2(SP)
ELSE
CMP.L #'LINK',(SP)+
ENDIF
BEQ.S @goodUNLK
_Debugger
@goodUNLK:
IF &preserve THEN
MOVE.W (SP)+,CCR
ADDQ.W #4,SP
ENDIF
ENDIF
UNLK A6
ELSE
IF debug THEN
BRA.S @skipUNLK
UNLK A6
@skipUNLK:
ENDIF
ENDIF
&LINKState: SETC ''
ENDM
;Fake RTS.
MACRO
noRTS
IF debug THEN
BRA.S @skipRTS
RTS
@skipRTS:
ENDIF
ENDM
;RTS.
MACRO
doRTS
RTS
ENDM
;RTD (uses A0).
MACRO
doRTD &size
LCLA &bytes
IF &size = '' THEN
&bytes: SETA ParameterSize
ELSEIF &SubStr(&size, 1, 1) = '#' THEN
&bytes: SETA &StrToInt(&SubStr(&size, 2, &Length(&size)-1))
ELSE
AERROR 'doRTD: bad size'
ENDIF
IF &bytes = 0 THEN
RTS
ELSEIF &bytes = 4 THEN
MOVE.L (SP)+,(SP)
RTS
ELSEIF &bytes <= 8 THEN
MOVE.L (SP)+,A0
ADDQ.W #&bytes,SP
JMP (A0)
ELSE
MOVE.L (SP)+,A0
LEA &bytes(SP),SP
JMP (A0)
ENDIF
ENDM
;Symbol.
MACRO
Symbol &routineName
LCLC &name
IF debug THEN
IF &routineName='' THEN
&name: SETC &SysMod
ELSEIF &routineName[1]='''' THEN
&name: SETC &SubStr(&routineName,2,&Len(&routineName)-2)
ELSE
&name: SETC &routineName
ENDIF
&name: SETC &SubStr(&Concat(&name, ' '),1,8)
DC.B &Ord(&name[1])+$80,&Ord(&name[2]),&Ord(&name[3]),&Ord(&name[4])
DC.B &Ord(&name[5]),&Ord(&name[6]),&Ord(&name[7]),&Ord(&name[8])
ENDIF
ENDM
;Define constant storage.
MACRO
DCS &recordName
DCB.B &recordName..size,0
ENDM
;Set up a patch table.
MACRO
PatchTable &thePatchStart
GBLC &patchStart
&patchStart: SETC &thePatchStart
ENDM
;Set up a patch table entry.
MACRO
DP &key,&patch,&old
GBLC &patchStart
IF &key='' THEN
DC.W 0
ELSE
DC.W &key
IF &patch='' THEN
DC.W 0
ELSE
DC.W Patch&patch-&patchStart
ENDIF
IF &old='' THEN
DC.W 0
ELSE
DC.W Old&old-&patchStart
ENDIF
ENDIF
ENDM
;Set up a JMP to be patched.
MACRO
PJMP &label
DC.W $4EF9
Old&label: DC.L 0
ENDM
;Set up a JSR to be patched.
MACRO
PJSR &label
DC.W $4EB9
Old&label: DC.L 0
ENDM